package laboratorioV.grupo21.tp4.deposito;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.LinkedHashMap;
import laboratorioV.grupo21.tp4.clientes.Cliente;
import laboratorioV.grupo21.tp4.clientes.ClientesFromDB;
import laboratorioV.grupo21.tp4.productos.Producto;
import laboratorioV.grupo21.tp4.productos.ProductosFromDB;

public class Deposito implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 2804432645600452242L;
	private String nombre;
	private LinkedHashMap<Integer,Pasillo> pasillos;
	
	public Deposito() {
		setNombre("Mercaderia de Multiproposito");
		pasillos = new LinkedHashMap<Integer, Pasillo>();
	}
	
	public void addPasillo(Integer numero, Pasillo obj){
		try {
			pasillos.put(numero, obj);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		//getPasillos().put(numero, obj);
	}
	
	

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public String getNombre() {
		return nombre;
	}

	public void setPasillos(LinkedHashMap<Integer,Pasillo> pasillos) {
		this.pasillos = pasillos;
	}

	
	public LinkedHashMap<Integer,Pasillo> getPasillos() {
		return pasillos;
	}
	
	public Pasillo getPasillo(Integer pNumPasillo){
		return pasillos.get(pNumPasillo);
		
	}

	public synchronized Integer addStock(Cliente clienteAux, Producto productoAux, Integer cantidadRestante) {
		/*
		 * RECORRE TODO EL DEPOSITO, AGREGA EL STOCK QUE PUEDA (SEGUN EL ESPACIO LIBRE)
		 * EN CADA COMPARTIMENTO QUE EXISTA Y QUE CONTENTA EL MISMO TIPO DE PRODUCTO
		 */
		Compartimiento compartimento = null;
		Pasillo pasilloAux;
		Lado ladoAux;
		if(clienteAux!= null && productoAux != null){
			for (Integer idPasillo : this.getPasillos().keySet()) {
				pasilloAux = this.getPasillo(idPasillo) ;
				
				//LADO DERECHO
				ladoAux = pasilloAux.getLadoDer();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"D",i,j);
						if(compartimento != null){
							if (compartimento.getProducto().equals(productoAux) ==true)
								cantidadRestante = compartimento.saveStock(idPasillo,"D",i,j,clienteAux, cantidadRestante,true);
							if(cantidadRestante == 0)					
								return cantidadRestante;
						}
					}
				}
					
				//LADO IZQUIERDO
				ladoAux = pasilloAux.getLadoIzq();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"I",i,j);
						if(compartimento != null){
							if (compartimento.getProducto().equals(productoAux) ==true)
								cantidadRestante = compartimento.saveStock(idPasillo,"I",i,j, clienteAux, cantidadRestante,true);
							if(cantidadRestante == 0)					
								return cantidadRestante;
						}
					}
				}					
			}
		}
		
		return cantidadRestante;
				
	}
	
	public synchronized Compartimiento getCompartimento(Integer pIdPasillo, String pLado,
			Integer pFila, Integer pColumna) {
		
		PreparedStatement ps = null;		
		Connection con = null;		
		Compartimiento compartimento = null;
		
		try{
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
			
			con = DriverManager.getConnection("jdbc:derby:derbyDb/TP6;create=false");
						
			String strSQL = "SELECT ID_PRODUCTO, ID_CLIENTE, STOCK FROM STOCK WHERE DEPOSITO = ? AND ID_PASILLO = ? AND LADO = ? AND FILA = ? AND COLUMNA = ?";
			ps = con.prepareCall(strSQL, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
			
			ps.setString(1, this.getNombre());
			ps.setInt(2, pIdPasillo);
			ps.setString(3, pLado);
			ps.setInt(4, pFila);
			ps.setInt(5, pColumna);
			java.sql.ResultSet rs = ps.executeQuery();
		    
		   
		    while(rs.next()){
		    	//System.out.print( rs.getInt(1) + "||" + rs.getString(2) + "||" + rs.getInt(3) );
		    	if(rs.isFirst()){
		    		Integer id = rs.getInt(1);
		    		Producto pro = new ProductosFromDB().getById(id.toString());
		    		compartimento = new Compartimiento(pro , 100);
		    	}
		    		
		    	
		    	compartimento.addStock(new ClientesFromDB().getById(rs.getString(2)), rs.getInt(3));			    
		    }			
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
		}
		finally{
			try {
				if(con != null)con.close();
				return compartimento;
			} catch (SQLException e) {				
				e.printStackTrace();
			}
			
		}
		
		return null;
	}

	public synchronized Integer nuevoCompartimento(Cliente clienteAux, Producto productoAux, Integer cantidadRestante) throws Exception {
		Compartimiento compartimento = null;
		Pasillo pasilloAux;
		Lado ladoAux;
		if(clienteAux!= null && productoAux != null){			
			for (Integer idPasillo : this.getPasillos().keySet()) {
				pasilloAux = this.getPasillo(idPasillo) ;
				
				//LADO DERECHO
				ladoAux = pasilloAux.getLadoDer();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"D",i,j);
						if(compartimento == null){
							compartimento = new Compartimiento(productoAux, 100);
							cantidadRestante = compartimento.saveStock(idPasillo,"D",i,j,clienteAux, cantidadRestante,false);
							if(cantidadRestante == 0)					
								return cantidadRestante;
						}
					}
				}
					
				//LADO IZQUIERDO
				ladoAux = pasilloAux.getLadoIzq();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"I",i,j);
						if(compartimento == null){
							compartimento = new Compartimiento(productoAux, 100);
							cantidadRestante = compartimento.saveStock(idPasillo,"I",i,j, clienteAux, cantidadRestante,false);
							if(cantidadRestante == 0)					
								return cantidadRestante;
						}
					}
				}					
			}			
		}		
		return cantidadRestante;		
	}
	
	public HashSet<Producto>  getProductosDeCliente(Cliente client){
		HashSet<Producto> setProductosCliente = new HashSet<Producto>();
		Producto productoAux = null;	
		Compartimiento compartimento = null;
		Pasillo pasilloAux;		
		Lado ladoAux;
		
			for (Integer idPasillo : this.getPasillos().keySet()) {
				pasilloAux = this.getPasillo(idPasillo) ;
				
				//LADO DERECHO
				ladoAux = pasilloAux.getLadoDer();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"D",i,j);
						if(compartimento != null){
							if(compartimento.contains(client))
								//Si el compartimento guarda stock del cliente
								//obtiene el producto que se guarda en el compartimento
								productoAux = compartimento.getProducto();

								//Agrega el producto a un set para no repetirlo
								setProductosCliente.add(productoAux);						
						}
					}
				}
					
				//LADO IZQUIERDO
				ladoAux = pasilloAux.getLadoIzq();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"I",i,j);
						if(compartimento != null){
							if(compartimento.contains(client))
								//Si el compartimento guarda stock del cliente
								//obtiene el producto que se guarda en el compartimento
								productoAux = compartimento.getProducto();

								//Agrega el producto a un set para no repetirlo
								setProductosCliente.add(productoAux);						
						}
					}
				}					
			}				
		
		
		return setProductosCliente;
	}
	
	public Integer getStockClienteProducto(Cliente client, Producto product){
		Compartimiento compartimento = null;
		Pasillo pasilloAux;		
		Lado ladoAux;		
		Integer stock = 0;
		Integer stockComp = 0;
		
			for (Integer idPasillo : this.getPasillos().keySet()) {
				pasilloAux = this.getPasillo(idPasillo) ;
				
				//LADO DERECHO
				ladoAux = pasilloAux.getLadoDer();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"D",i,j);
						if(compartimento != null){
							if(compartimento.contains(client))
								if(compartimento.getProducto().equals(product)){
									stockComp = compartimento.getStockCliente(client);
									stock += stockComp;
								}							
						}
					}
				}
					
				//LADO IZQUIERDO
				ladoAux = pasilloAux.getLadoIzq();
				for (Integer i = 1; i <= ladoAux.getCantidadCompartimentosMaxX(); i++) {
					for (Integer j = 1; j < ladoAux.getCantidadCompartimentosMaxY(); j++) {
						compartimento = this.getCompartimento(idPasillo,"I",i,j);
						if(compartimento != null){
							if(compartimento.contains(client))
								if(compartimento.getProducto().equals(product)){
									stockComp = compartimento.getStockCliente(client);
									stock += stockComp;
								}							
						}
					}
				}					
			}				
		return stock;		
	}
	
}
